import { DatePicker as NutDatePicker } from '@nutui/nutui-react-taro';
import dayjs, { Dayjs } from 'dayjs';
import { useMemo, useState } from 'react';
import { View } from '@tarojs/components';

import PickerView, { type PickerViewProps } from '../PickerView';
import { Icon } from '@/components';

import type { DatePickerProps as NutDatePickerProps } from '@nutui/nutui-react-taro';
import type { PickerOption } from '@nutui/nutui-react-taro/dist/types/packages/picker';
import type { FC } from 'react';

import './index.scss';

import {
  DATE_FORMAT,
  HOUR_FORMAT,
  MINUTE_FORMAT,
  MONTH_FORMAT,
  TIME_FORMAT,
} from '@/constants';

interface DatePickerProps
  extends Partial<
    Omit<
      NutDatePickerProps,
      'visible' | 'defaultValue' | 'value' | 'onConfirm' | 'onChange'
    >
  > {
  defaultValue?: string;
  value?: string;
  onConfirm?: (option: PickerOption[], value: Dayjs) => void;
  onCancel?: () => void;
  onChange?: (v: string) => void;
  clearable?: boolean;
  pickerViewProps?: PickerViewProps;
  // 新增：可见性回调
  onVisibleChange?: (visible: boolean) => void;
  onPopupOpen?: () => void;
  onPopupClose?: () => void;
}

const formatTypeMap = new Map<DatePickerProps['type'], string>([
  ['date', DATE_FORMAT],
  ['time', TIME_FORMAT],
  ['year-month', MONTH_FORMAT],
  ['month-day', 'MM-DD'],
  ['datehour', `${DATE_FORMAT} ${HOUR_FORMAT}`],
  ['datetime', `${DATE_FORMAT} ${MINUTE_FORMAT}`],
  ['hour-minutes', MINUTE_FORMAT],
]);

const DatePicker: FC<DatePickerProps> = ({
  type,
  defaultValue,
  value,
  onConfirm,
  onCancel,
  onClose,
  onChange,
  clearable = true,
  pickerViewProps,
  onVisibleChange,
  onPopupOpen,
  onPopupClose,
  ...rest
}) => {
  const [visible, setVisible] = useState<boolean>(false);

  const text = useMemo(() => {
    if (!value) return null;
    return dayjs(value)?.format(formatTypeMap.get(type));
  }, [type, value]);

  const handleClear = (e: any) => {
    e.stopPropagation();
    onChange?.('');
  };

  const handleOpen = () => {
    setVisible(true);
    onVisibleChange?.(true);
    onPopupOpen?.();
  };

  const handleClose = () => {
    onVisibleChange?.(false);
    onPopupClose?.();
    setVisible(false);
    onCancel?.();
    onClose?.();
  };

  return (
    <>
      <View className="date-picker-wrapper">
        <PickerView text={text} {...pickerViewProps} onClick={handleOpen} />
        {text && clearable && (
          <View className="clear-button" onClick={handleClear}>
            <Icon name="CloseOutlined" size={16} />
          </View>
        )}
      </View>
      <NutDatePicker
        visible={visible}
        type={type}
        defaultValue={defaultValue ? dayjs(defaultValue)?.toDate() : undefined}
        value={value ? dayjs(value)?.toDate() : undefined}
        onConfirm={(option, value) => {
          console.log('onConfirm', option, value);
          let year = dayjs().year();
          let month = dayjs().month() + 1;
          let date = dayjs().date();
          let hour = dayjs().hour();
          let minute = dayjs().minute();
          let second = dayjs().second();
          if (type === 'date') {
            year = Number(value[0]);
            month = Number(value[1]);
            date = Number(value[2]);
          } else if (type === 'time') {
            hour = Number(value[0]);
            minute = Number(value[1]);
            second = Number(value[2]);
          } else if (type === 'year-month') {
            year = Number(value[0]);
            month = Number(value[1]);
          } else if (type === 'month-day') {
            month = Number(value[0]);
            date = Number(value[1]);
          } else if (type === 'datehour') {
            year = Number(value[0]);
            month = Number(value[1]);
            date = Number(value[2]);
            hour = Number(value[3]);
          } else if (type === 'datetime') {
            year = Number(value[0]);
            month = Number(value[1]);
            date = Number(value[2]);
            hour = Number(value[3]);
            minute = Number(value[4]);
          } else if (type === 'hour-minutes') {
            hour = Number(value[0]);
            minute = Number(value[1]);
          }

          const v = dayjs()
            .year(year)
            .month(month - 1)
            .date(date)
            .hour(hour)
            .minute(minute)
            .second(second);
          onConfirm?.(option, v);
          onChange?.(dayjs(v).format(formatTypeMap.get(type)));
        }}
        onClose={handleClose}
        {...rest}
      />
    </>
  );
};

export default DatePicker;
